﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;

namespace FTP客户端
{
    public partial class MainForm2 : Form
    {
        Point mouseOff;//用于获取鼠标位置
        bool leftFlag;//移动标识
        private AnotherForm parent;
        public MainForm2(AnotherForm parent)
        {
            this.parent = parent;
            this.parent.Hide();
            this.StartPosition = FormStartPosition.CenterScreen;
            InitializeComponent();
        }

        private void MainForm2_Load(object sender, EventArgs e)
        {

        }

        //上传的方法   
        private void Upload(string filename)
        {
            string ftpServerIP, ftpUserID, ftpPassword;
            ftpServerIP = this.parent.ftpServerIP;
            ftpUserID = this.parent.ftpUserID;
            ftpPassword = this.parent.ftpPassword;

            FileInfo fileInf = new FileInfo(filename);
            string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
            FtpWebRequest reqFTP;
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));

            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
            reqFTP.KeepAlive = false;
            reqFTP.UsePassive = false;
            reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
            reqFTP.UseBinary = true;
            reqFTP.ContentLength = fileInf.Length;

            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int contentLen;

            using (FileStream fs = fileInf.OpenRead())
            {
                try
                {
                    using (Stream strm = reqFTP.GetRequestStream())
                    {
                        contentLen = fs.Read(buff, 0, buffLength);
                        while (contentLen != 0)
                        {
                            strm.Write(buff, 0, contentLen);
                            contentLen = fs.Read(buff, 0, buffLength);
                        }
                    }
                    MessageBox.Show("上传成功！");
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"上传失败：{ex.Message}");
                }
            }
        }

        //删除功能   
        public void DeleteFTP(string fileName)
        {
            try
            {
                string ftpServerIP, ftpUserID, ftpPassword;
                ftpServerIP = this.parent.ftpServerIP;
                ftpUserID = this.parent.ftpUserID;
                ftpPassword = this.parent.ftpPassword;

                string uri = "ftp://" + ftpServerIP + "/" + fileName;
                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));

                reqFTP.Credentials = new NetworkCredential();
                reqFTP.KeepAlive = false;
                reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
                reqFTP.UsePassive = false;
                string result = String.Empty;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                long size = response.ContentLength;
                Stream datastream = response.GetResponseStream();
                StreamReader sr = new StreamReader(datastream);
                result = sr.ReadToEnd();
                sr.Close();
                datastream.Close();
                response.Close();
                MessageBox.Show("删除成功!");

            }
            catch
            {
                MessageBox.Show("删除失败，刷新或稍后再试!");
            }
        }

        //获取文件列表方法   
        public string[] GetFileList()
        {
            string[] downloadFiles;
            StringBuilder result = new StringBuilder();
            FtpWebRequest reqFTP;
            FtpWebResponse response = null;

            try
            {
                // 创建FtpWebRequest
                reqFTP = CreateFtpWebRequest();

                // 获取FtpWebResponse
                response = (FtpWebResponse)reqFTP.GetResponse();

                // 使用using语句确保StreamReader正确释放资源
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        result.Append(line);
                        result.Append("\n");
                    }
                }

                if (result.Length > 0)
                {
                    result.Remove(result.Length - 1, 1);
                }

                downloadFiles = result.ToString().Split('\n');
            }
            catch (WebException ex)
            {
                // 处理FTP相关的异常
                MessageBox.Show($"FTP操作出错：{ex.Message}");
                downloadFiles = null;
            }
            catch (Exception ex)
            {
                // 处理其他异常
                MessageBox.Show($"发生未知错误：{ex.Message}");
                downloadFiles = null;
            }
            finally
            {
                // 确保response被关闭
                if (response != null)
                {
                    response.Close();
                }
            }

            return downloadFiles;
        }

        private FtpWebRequest CreateFtpWebRequest()
        {
            FtpWebRequest reqFTP;

            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + this.parent.ftpServerIP + "/"));
            reqFTP.Credentials = new NetworkCredential(this.parent.ftpUserID, this.parent.ftpPassword);

            reqFTP.UseBinary = true;
            reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
            reqFTP.UsePassive = false;

            return reqFTP;
        }

        // 获取文件详细信息列表   
        private string[] GetFilesDatailList(string filename)
        {
            // 如果失败，返回 null 信息。
            string[] ret = null;
            try
            {
                string ftpServerIP, ftpUserID, ftpPassword;

                // 获取 FTP 服务器信息
                ftpServerIP = this.parent.ftpServerIP;
                ftpUserID = this.parent.ftpUserID;
                ftpPassword = this.parent.ftpPassword;
               
                // 获取文件类型
                string fileType = Path.GetExtension(filename);
                if (!string.IsNullOrEmpty(fileType))
                {
                    fileType = fileType.TrimStart('.'); // 去除前导点
                }

                // 构建 FTP 请求
                FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri($"ftp://{ftpServerIP}/{filename}"));
                ftp.Credentials = new NetworkCredential();
                ftp.Method = WebRequestMethods.Ftp.GetFileSize; // 获取文件大小
                ftp.UsePassive = false;

                // 获取文件大小
                using (WebResponse response = ftp.GetResponse())
                {
                    long fileSize = response.ContentLength;
                    ret = new string[5];
                    ret[0] = filename; // 文件名
                    ret[1] = fileSize.ToString(); // 文件大小
                    ret[2] = fileType; // 文件类型
                }

                // 获取文件最后修改时间
                ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri($"ftp://{ftpServerIP}/{filename}"));
                ftp.Credentials = new NetworkCredential();
                ftp.Method = WebRequestMethods.Ftp.GetDateTimestamp; // 获取文件最后修改时间
                ftp.UsePassive = false;
                using (WebResponse response = ftp.GetResponse())
                {
                    DateTime lastModified = ((FtpWebResponse)response).LastModified;
                    ret[3] = lastModified.ToString(); // 最后修改时间
                }

                // 获取文件权限
                ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri($"ftp://{ftpServerIP}/{filename}"));
                ftp.Credentials = new NetworkCredential();
                ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails; // 获取文件详细信息
                ftp.UsePassive = false;
                using (WebResponse response = ftp.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            string[] info = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                            if (info[8] == filename)
                            {
                                ret[4] = info[0]; // 权限
                                break;
                            }
                        }
                    }
                }

                return ret;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return ret;
            }
        }


        //下载方法   
        private void Download(string filePath, string fileName)
        {
            string ftpServerIP, ftpUserID, ftpPassword;
            ftpServerIP = this.parent.ftpServerIP;
            ftpUserID = this.parent.ftpUserID;
            ftpPassword = this.parent.ftpPassword;

            FtpWebRequest reqFTP;
            Uri u = new Uri("ftp://" + ftpServerIP + "/" + fileName);
            try
            {
                FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);

                reqFTP = (FtpWebRequest)FtpWebRequest.Create(u);

                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                reqFTP.UseBinary = true;
                reqFTP.UsePassive = false;
                reqFTP.Credentials = new NetworkCredential();
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];

                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }

                ftpStream.Close();
                outputStream.Close();
                response.Close();
            }
            catch
            {

            }
        }

        //重命名方法   
        private void Rename(string currentFilename, string newFilename)
        {
            string ftpServerIP, ftpUserID, ftpPassword;
            ftpServerIP = this.parent.ftpServerIP;
            ftpUserID = this.parent.ftpUserID;
            ftpPassword = this.parent.ftpPassword;

            FtpWebRequest reqFTP;
            try
            {
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + currentFilename));
                reqFTP.Method = WebRequestMethods.Ftp.Rename;
                reqFTP.RenameTo = newFilename;
                reqFTP.UseBinary = true;
                reqFTP.UsePassive = false;
                reqFTP.Credentials = new NetworkCredential();
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream ftpStream = response.GetResponseStream();

                ftpStream.Close();
                response.Close();
                MessageBox.Show("重命名成功!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //文件列表
        private void fileListBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            Color foreColor;
            Font font;
            e.DrawBackground();
            if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
            {//如果当前行为选中行。
             //绘制选中时要显示的蓝色边框。
                Color c = SystemColors.ControlDark;
                foreColor = Color.Black; //Color.FromArgb(6, 82, 121);
                font = new Font("黑体", 11, FontStyle.Bold);
                e.Graphics.FillRectangle(new SolidBrush(c), e.Bounds);//绘制背景
            }
            else
            {
                font = e.Font;
                foreColor = e.ForeColor;
            }

            //  e.DrawFocusRectangle();
            StringFormat strFmt = new System.Drawing.StringFormat();
            strFmt.Alignment = StringAlignment.Center; //文本垂直居中
            strFmt.LineAlignment = StringAlignment.Center; //文本水平居中

            e.Graphics.DrawString(fileListBox.Items[e.Index].ToString(), font, new SolidBrush(foreColor), e.Bounds, strFmt);
        }

        private void MainWindow_MouseDown(object sender, MouseEventArgs e)
        {
            mouseOff = new Point(e.X, e.Y);//获取当前鼠标位置
            leftFlag = true;//用于标记窗体是否能移动(此时鼠标按下如果说用户拖动鼠标则窗体移动)
        }

        private void MainWindow_MouseMove(object sender, MouseEventArgs e)
        {
            if (leftFlag)
            {
                Location = new Point(Control.MousePosition.X - mouseOff.X, Control.MousePosition.Y - mouseOff.Y);
            }
        }

        private void MainWindow_MouseUp(object sender, MouseEventArgs e)
        {
            if (leftFlag)
            {
                leftFlag = false; //释放鼠标标识为false 表示窗体不可移动
            }
        }

        private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.parent.Close();
        }

        private void fileListBox_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            e.ItemHeight = 40;
        }

        private void MainWindow_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                this.parent.Hide();
            }
            if (this.parent.ftpUserID == "test")
            {
                this.InfoLabel.Text = "Test Mode.";
            }
            else
            {
                this.InfoLabel.Text = $"Welcome! {this.parent.ftpUserID}. ";
            }
        }

        private void closeBtn_MouseEnter(object sender, EventArgs e)
        {
            this.closeBtn.BackgroundImage = (System.Drawing.Image)Properties.Resources.ResourceManager.GetObject("close_clicked");
        }

        private void closeBtn_MouseLeave(object sender, EventArgs e)
        {
            this.closeBtn.BackgroundImage = (System.Drawing.Image)Properties.Resources.ResourceManager.GetObject("close");
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {

        }

        //显示文件目录中已选的详细信息
        private void fileListBox_SelectedIndexChanged_1(object sender, EventArgs e)
        {

            if (fileListBox.SelectedItem != null)
            {
                string filename = fileListBox.SelectedItem.ToString();
                filenameBox.Text = filename;
                string[] details = GetFilesDatailList(filename);
                titleLabel.Text = filename;
                if (details == null)
                {
                    DetailLabel.Text = "无法获取文件的详细信息！请重试";
                }
                else
                {
                    DetailLabel.Text = $"文件名: {details[0]}\n文件大小: {details[1]}\n文件类型: {details[2]}\n最后一次修改时间: \n{details[3]}\n文件权限: {details[4]}";
                }
            }
        }


        private void getFileBtn_Click_1(object sender, EventArgs e)
        {
            string[] filenames = this.GetFileList();
            fileListBox.Items.Clear();
            try
            {
                foreach (string filename in filenames)
                {
                    fileListBox.Items.Add(filename);
                }
            }
            catch
            {

            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
        
        private void detailButton_Click(object sender, EventArgs e)
        {
            string ftpServerIP, ftpUserID, ftpPassword;
            ftpServerIP = this.parent.ftpServerIP;
            ftpUserID = this.parent.ftpUserID;
            ftpPassword = this.parent.ftpPassword;

            // 检查是否有文件被选中
            if (fileListBox.SelectedItem == null)
            {
                MessageBox.Show("请选择文件!");
            }
            else
            {
                string filename = fileListBox.SelectedItem.ToString();

                // 获取文件的详细信息
                string[] details = GetFilesDatailList(filename);

                if (details == null)
                {
                    MessageBox.Show("无法获取文件的详细信息！请重试");
                }
                else
                {
                    // 显示文件的详细信息
                    // 显示文件的详细信息
                    // 显示文件的详细信息   
                    MessageBox.Show(
                        $"Raw response from server to {ftpServerIP}:\n" +
                        $"文件名: {details[0]}\n" +
                        $"文件大小: {details[1]}\n" +
                        $"文件类型: {details[2]}\n" +
                        $"最后一次修改时间: {details[3]}\n" +
                        $"文件权限: {details[4]}");
                }
            }
        }

        private void renameBtn_Click(object sender, EventArgs e)
        {
            if (fileListBox.SelectedItem == null)
            {
                MessageBox.Show("必须选中你想要重命名的文件！");
            }
            else
            {
                string currentFileName = fileListBox.SelectedItem.ToString();
                string newFileName = filenameBox.Text.ToString();
                DialogResult dr = MessageBox.Show($"确认要重命名文件{currentFileName}->{newFileName}吗?", "确认重命名",
                    MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.OK)
                {
                    if (newFileName.Trim() != "")
                    {
                        Rename(currentFileName, newFileName);
                        getFileBtn_Click_1(null, null);
                    }
                    else
                    {
                        MessageBox.Show("重命名不能为空!");
                    }
                }
            }
        }

        private void downloadBtn_Click(object sender, EventArgs e)
        {
            if (fileListBox.SelectedItem == null)
            {
                MessageBox.Show("请选择需要下载的文件!");
                return;
            }
            FolderBrowserDialog fldDlg = new FolderBrowserDialog();
            string fileName = fileListBox.SelectedItem.ToString();
            if (fileName != string.Empty)
            {
                if (fldDlg.ShowDialog() == DialogResult.OK)
                {
                    Download(fldDlg.SelectedPath, fileName);
                }
            }
            else
            {
                MessageBox.Show("请选择下载的文件！");
            }
        }

        private void deleteBtn_Click(object sender, EventArgs e)
        {
            if (fileListBox.SelectedItem == null)
            {
                MessageBox.Show("请选择你需要删除的文件!");
            }
            else
            {
                string fileName = fileListBox.SelectedItem.ToString();
                DialogResult dr = MessageBox.Show($"确认要删除文件{fileName}吗?", "确认删除",
                    MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.OK)
                {
                    DeleteFTP(fileName);
                    getFileBtn_Click_1(null, null);

                }
            }
        }

        private void uploadBtn_Click_1(object sender, EventArgs e)
        {
            OpenFileDialog opFilDIg = new OpenFileDialog();
            if (opFilDIg.ShowDialog() == DialogResult.OK)
            {
                Upload(opFilDIg.FileName);
                getFileBtn_Click_1(null, null);

            }
        }

        private void getFileBtn_Click(object sender, EventArgs e)
        {
            string[] filenames = this.GetFileList();
            fileListBox.Items.Clear();
            try
            {
                foreach (string filename in filenames)
                {
                    fileListBox.Items.Add(filename);
                }
            }
            catch
            {

            }
        }

        private void backBtn_Click(object sender, EventArgs e)
        {
            this.parent.Show();
            this.Hide();
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}



